<?php

namespace app\api\controller\Online;

use app\api\controller\Common;
use app\api\Logic\Online\OnlineVideoLogic;
use app\api\Logic\Online\OnlineVideoOrderLogic;
use app\api\Logic\Online\OnlineVideoSublevelLogic;
use app\api\model\OnlineVideoModel;
use app\api\model\OnlineVideoSublevelLogModel;
use app\api\model\OnlineVideoSublevelModel;
use think\Db;
use think\Exception;
use think\exception\DbException;

/**
 * 在线课程接口
 */
class Video extends Common
{
    protected $noNeedLogin = ['*'];

    protected $onlineVideoLogic;
    protected $onlineVideoOrderLogic;
    protected $onlineVideoSublevelLogic;

    public function _initialize()
    {
        parent::_initialize();
        $this->onlineVideoLogic = new OnlineVideoLogic();
        $this->onlineVideoOrderLogic = new OnlineVideoOrderLogic();
        $this->onlineVideoSublevelLogic = new OnlineVideoSublevelLogic();
    }

    /**
     * 获取方式映射
     * @return array[]
     */
    protected function getTypeMap(){
        return [
            0 => ['type' => 0, 'name' => '不限方式'],
            1 => ['type' => 1, 'name' => '付费购买'],
            2 => ['type' => 2, 'name' => '免费'],
        ];
    }

    /**
     * 排序映射
     * @return array[]
     */
    protected function orderMap(){
        return [
            1 => ['type' => 1, 'name' => '最多学习'],
            2 => ['type' => 2, 'name' => '最新上架'],
        ];
    }

    /**
     * 供前端调用，返回获取方式
     */
    public function getTypeAry(){
        $list = array_values($this->getTypeMap());
        if (!empty($list)) {
            $this->success('查询成功', $list);
        }
        $this->error('暂无数据');
    }

    /**
     * 供前端调用，返回排序方式
     */
    public function orderAry(){
        $list = array_values($this->orderMap());
        if (!empty($list)) {
            $this->success('查询成功', $list);
        }
        $this->error('暂无数据');
    }

    /**
     * 在线课程列表
     * @throws Exception
     * @throws DbException
     */
    public function getList(){
        if ($this->request->isPost()) {
            $param = $this->request->param();
            //验证数据
            $param = $this->verifyData($param);

            //校区ID
            $shopId = $param['shop_id'] ?? 0;
            //排序方式
            $order = $param['order'] ?? 0;

            $query = OnlineVideoModel::where('shop_id',$shopId);
            //根据分类筛选
            if(isset($param['type_id']) && !empty($param['type_id'])){
                $query = $query->where('type',$param['type_id']);
            }
            //根据获取方式筛选
            if(isset($param['get_type']) && $param['get_type'] != 0){
                //付费购买
                if($param['get_type'] == 1){
                    $query = $query->where('price','>',0);
                }else if($param['get_type'] == 2){
                    $query = $query->where('price','<=',0);
                }
            }

            //排序方式
            if($order){
                //最多学习
                if($order == 1){
                    $query = $query->order('study_number','desc');
                }else if($order == 2){
                    //最新上架
                    $query = $query->where('create_time','desc');
                }
            }

            //获取列表
            $list = $query->with([
                    'videoTypeInfo' => function ($query) {
                        $query->withField('id,name');
                    }
                ])
//                ->page($param['page'],$param['page_size'])
                ->field('id,shop_id,type_id,title,image,price,study_number')
                ->paginate(PAGE_SIZE);
            $list = objToArray($list) ?? [];

            foreach ($list['data'] as $key => $val){
                //获取课程的章节数
                $list['data'][$key]['sublevel_num'] = OnlineVideoSublevelModel::where('video_id',$val['id'])
                    ->whereNull('deletetime')
                    ->count('id');
            }

            if(!empty($list)){
                $this->success('查询成功',$list);
            }
            $this->error('暂无数据');
        }
        $this->error('请求错误');
    }

    /**
     * 课程详情
     */
    public function info(){
        if ($this->request->isPost()) {
            $param = $this->request->param();
            //验证数据
            $param = $this->verifyData($param);

            if(!isset($param['video_id']) || empty($param['video_id'])){
                $this->error('在线课程ID必须');
            }

            //获取课程详情
            $info = $this->onlineVideoLogic->getInfo($param['shop_id'],$param['video_id']);

            //章节学习状态
            if(!empty($info['sublevel_list'])){
                foreach ($info['sublevel_list'] as $key => $val){
                    //获取章节学习记录
                    $logInfo = $this->onlineVideoSublevelLogic->sublevelStudyLog($param['video_id'],$val['id']);
                    if(empty($logInfo)){
                        $info['sublevel_list'][$key]['is_study'] = false;
                    }else{
                        $info['sublevel_list'][$key]['is_study'] = true;
                    }
                }
            }

            //获取是否已支付该课程
            $orderInfo = $this->onlineVideoOrderLogic->getOrderInfoByVideoId($param['shop_id'],$param['video_id']);
            $info['is_buy'] = false;
            if(!empty($orderInfo) && $orderInfo['status'] == 2){
                $info['is_buy'] = true;
            }

            if(!empty($info)){
                $this->success('查询成功',$info);
            }
            $this->error('暂无数据');
        }
        $this->error('请求错误');
    }

    /**
     * 学习视频某章节
     */
    public function study(){
        if($this->request->isPost()){
            $param = $this->request->param();
            //验证数据
            $param = $this->verifyData($param);

            if(!isset($param['video_id']) || empty($param['video_id'])){
                $this->error('在线课程ID必须');
            }
            if(!isset($param['sublevel_id']) || empty($param['sublevel_id'])){
                $this->error('章节ID必须');
            }
            //学习时长
            $studyTime = $param['study_time'] ?? 0;
            if(empty($studyTime)){
                $this->error('学习时长必须');
            }

            //查询章节信息
            $sublevelInfo = $this->onlineVideoSublevelLogic->sublevelInfo($param['video_id'],$param['sublevel_id']);
            if(empty($sublevelInfo)){
                $this->error('章节信息不存在');
            }

            Db::startTrans();
            try {
                //查询是否存在该章节观看记录
                $logInfo = $this->onlineVideoSublevelLogic->sublevelStudyLog($param['video_id'],$param['sublevel_id']);
                if(empty($logInfo)){
                    //未学习，则新增学习记录
                    $insertData = [
                        'shop_id' => $param['shop_id'],
                        'user_id' => $param['user_id'],
                        'video_id' => $param['video_id'],
                        'video_sublevel_id' => $param['sublevel_id'],
                        'first_time' => time(),
                        'study_time' => $studyTime,
                        'study_ratio' => !empty($sublevelInfo['video_length']) ? round($studyTime / $sublevelInfo['video_length'],2) : 1,
                        'status' => 1,
                        'createtime' => time(),
                    ];
                    OnlineVideoSublevelLogModel::insertGetId($insertData);
                }else{
                    //已学习，则修改学习时长
                    $totalStudyTime = $logInfo['study_time'] + $studyTime;  //总学习时长
                    $studyRatio = round($totalStudyTime / $sublevelInfo['video_length'],2);
                    $updateData = [
                        'study_time' => $totalStudyTime,
                        'study_ratio' => $studyRatio,
                        'status' => $studyRatio >= 1 ? 2 : 1
                    ];
                    OnlineVideoSublevelLogModel::where('id',$logInfo['id'])->update($updateData);
                }

                Db::commit();
                $this->success('操作成功');
            }catch (Exception $e){
                Db::rollback();
                $this->error('操作失败');
            }
        }
        $this->error('请求错误');
    }
}
